<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Kafka 数据清理与过期策略深度解析</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            min-height: 100vh;
        }
        
        .hero-gradient {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        
        .content-card {
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(10px);
            transition: all 0.3s ease;
        }
        
        .content-card:hover {
            transform: translateY(-2px);
            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
        }
        
        .section-title {
            position: relative;
            padding-left: 20px;
        }
        
        .section-title::before {
            content: '';
            position: absolute;
            left: 0;
            top: 50%;
            transform: translateY(-50%);
            width: 4px;
            height: 24px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 2px;
        }
        
        .code-inline {
            background: #f3f4f6;
            padding: 2px 8px;
            border-radius: 4px;
            font-family: 'Courier New', monospace;
            font-size: 0.9em;
            color: #6366f1;
            border: 1px solid #e5e7eb;
        }
        
        .feature-icon {
            width: 60px;
            height: 60px;
            display: flex;
            align-items: center;
            justify-content: center;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 16px;
            color: white;
            font-size: 24px;
            margin-bottom: 16px;
        }
        
        .mermaid {
            display: flex;
            justify-content: center;
            margin: 2rem 0;
        }
        
        .timeline-item {
            position: relative;
            padding-left: 40px;
            margin-bottom: 24px;
        }
        
        .timeline-item::before {
            content: '';
            position: absolute;
            left: 10px;
            top: 8px;
            width: 12px;
            height: 12px;
            background: #667eea;
            border-radius: 50%;
            box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.2);
        }
        
        .timeline-item::after {
            content: '';
            position: absolute;
            left: 15px;
            top: 20px;
            width: 2px;
            height: calc(100% + 12px);
            background: #e5e7eb;
        }
        
        .timeline-item:last-child::after {
            display: none;
        }
        
        @keyframes fadeInUp {
            from {
                opacity: 0;
                transform: translateY(20px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }
        
        .animate-fadeInUp {
            animation: fadeInUp 0.6s ease-out;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <div class="hero-gradient text-white py-20">
        <div class="container mx-auto px-6">
            <div class="max-w-4xl mx-auto text-center animate-fadeInUp">
                <h1 class="text-5xl font-bold mb-6" style="font-family: 'Noto Serif SC', serif;">
                    Kafka 数据清理与过期策略
                </h1>
                <p class="text-xl opacity-90 leading-relaxed">
                    深入解析分布式消息系统的存储管理艺术
                </p>
                <div class="mt-8 flex justify-center space-x-8">
                    <div class="text-center">
                        <i class="fas fa-database text-3xl mb-2"></i>
                        <p class="text-sm opacity-80">高效存储</p>
                    </div>
                    <div class="text-center">
                        <i class="fas fa-clock text-3xl mb-2"></i>
                        <p class="text-sm opacity-80">智能过期</p>
                    </div>
                    <div class="text-center">
                        <i class="fas fa-compress text-3xl mb-2"></i>
                        <p class="text-sm opacity-80">灵活压缩</p>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Main Content -->
    <div class="container mx-auto px-6 py-12">
        <!-- Introduction -->
        <div class="max-w-4xl mx-auto mb-12">
            <div class="content-card rounded-2xl shadow-xl p-8">
                <p class="text-lg leading-relaxed text-gray-700" style="text-indent: 2em;">
                    Kafka作为一个高吞吐量的分布式消息系统，其数据清理与过期策略是保证系统性能和有效管理存储空间的关键组成部分。Kafka使用的清理机制主要包括基于时间的过期策略和基于大小的清理策略。
                </p>
            </div>
        </div>

        <!-- Data Storage Model -->
        <div class="max-w-4xl mx-auto mb-12">
            <div class="content-card rounded-2xl shadow-xl p-8">
                <h2 class="section-title text-2xl font-bold mb-6 text-gray-800">
                    <i class="fas fa-layer-group mr-3 text-purple-600"></i>数据存储模型
                </h2>
                <p class="text-gray-700 leading-relaxed" style="text-indent: 2em;">
                    Kafka中的数据以日志的形式存储，每个主题由多个分区组成，每个分区又由多个日志段（log segment）构成。这种结构使得Kafka能够高效地处理大量消息，但同时也需要合理的清理策略来管理这些数据。
                </p>
                
                <!-- Mermaid Diagram -->
                <div class="mermaid mt-8">
                    graph TD
                        A[Kafka Cluster] --> B[Topic 1]
                        A --> C[Topic 2]
                        B --> D[Partition 0]
                        B --> E[Partition 1]
                        D --> F[Log Segment 1]
                        D --> G[Log Segment 2]
                        D --> H[Log Segment N]
                        style A fill:#667eea,stroke:#fff,stroke-width:2px,color:#fff
                        style B fill:#764ba2,stroke:#fff,stroke-width:2px,color:#fff
                        style C fill:#764ba2,stroke:#fff,stroke-width:2px,color:#fff
                </div>
            </div>
        </div>

        <!-- Cleaning Strategies -->
        <div class="max-w-4xl mx-auto mb-12">
            <div class="content-card rounded-2xl shadow-xl p-8">
                <h2 class="section-title text-2xl font-bold mb-6 text-gray-800">
                    <i class="fas fa-broom mr-3 text-purple-600"></i>清理策略
                </h2>
                <p class="text-gray-700 mb-6">Kafka提供了两种主要的数据清理策略：</p>
                
                <div class="grid md:grid-cols-2 gap-6">
                    <div class="bg-gradient-to-br from-purple-50 to-pink-50 p-6 rounded-xl border border-purple-200">
                        <div class="feature-icon">
                            <i class="fas fa-hourglass-half"></i>
                        </div>
                        <h3 class="text-xl font-bold mb-3 text-gray-800">保留时间（Retention Time）</h3>
                        <p class="text-gray-700 mb-3">
                            每个主题都可以设置一个消息保留时间，当消息在Kafka中存储超过该时间后，系统会自动清理这些过期的消息。
                        </p>
                        <p class="text-sm text-gray-600">
                            配置参数：<span class="code-inline">retention.ms</span>
                        </p>
                    </div>
                    
                    <div class="bg-gradient-to-br from-blue-50 to-indigo-50 p-6 rounded-xl border border-blue-200">
                        <div class="feature-icon">
                            <i class="fas fa-hdd"></i>
                        </div>
                        <h3 class="text-xl font-bold mb-3 text-gray-800">保留大小（Retention Size）</h3>
                        <p class="text-gray-700 mb-3">
                            除了基于时间的清理，Kafka还允许配置每个主题的最大存储大小。当主题的存储大小超过该限制时，Kafka会删除最早的消息以释放空间。
                        </p>
                        <p class="text-sm text-gray-600">
                            配置参数：<span class="code-inline">retention.bytes</span>
                        </p>
                    </div>
                </div>
                
                <p class="text-gray-700 mt-6 text-center italic">
                    这两种策略可以单独使用，也可以组合使用，根据业务需求灵活设置。
                </p>
            </div>
        </div>

        <!-- Log Cleaning Mechanism -->
        <div class="max-w-4xl mx-auto mb-12">
            <div class="content-card rounded-2xl shadow-xl p-8">
                <h2 class="section-title text-2xl font-bold mb-6 text-gray-800">
                    <i class="fas fa-cogs mr-3 text-purple-600"></i>日志清理机制
                </h2>
                <p class="text-gray-700 mb-6">Kafka使用的日志清理机制主要有两种：</p>
                
                <div class="space-y-6">
                    <div class="bg-red-50 p-6 rounded-xl border-l-4 border-red-400">
                        <h3 class="text-xl font-bold mb-3 text-gray-800 flex items-center">
                            <i class="fas fa-trash-alt mr-3 text-red-500"></i>
                            删除（Delete）模式
                        </h3>
                        <p class="text-gray-700">
                            在这种模式下，Kafka根据设置的保留时间和大小，定期扫描分区中的日志文件，并删除那些过期的消息。这种方式适合大多数使用场景，因为它简单且易于理解。系统会在后台定期检查并清理过期数据，确保日志的有效性和存储空间的合理使用。
                        </p>
                    </div>
                    
                    <div class="bg-green-50 p-6 rounded-xl border-l-4 border-green-400">
                        <h3 class="text-xl font-bold mb-3 text-gray-800 flex items-center">
                            <i class="fas fa-compress-alt mr-3 text-green-500"></i>
                            压缩（Compact）模式
                        </h3>
                        <p class="text-gray-700">
                            另一种清理方式是压缩模式，Kafka在这种模式下保留每个键（key）最新的消息，同时删除旧版本的消息。这对于需要保持最新状态而又不需要完整历史记录的场景尤为适用，如数据库变更日志（Change Data Capture，CDC）。
                        </p>
                        <p class="text-sm text-gray-600 mt-2">
                            启用方式：设置 <span class="code-inline">cleanup.policy</span> 为 <span class="code-inline">compact</span>
                        </p>
                    </div>
                </div>
            </div>
        </div>

        <!-- Cleaning Process -->
        <div class="max-w-4xl mx-auto mb-12">
            <div class="content-card rounded-2xl shadow-xl p-8">
                <h2 class="section-title text-2xl font-bold mb-6 text-gray-800">
                    <i class="fas fa-sync-alt mr-3 text-purple-600"></i>清理过程
                </h2>
                <p class="text-gray-700 mb-6">Kafka的清理过程是异步的，具体步骤如下：</p>
                
                <div class="space-y-4">
                    <div class="timeline-item">
                        <h3 class="font-bold text-lg text-gray-800 mb-2">背景任务</h3>
                        <p class="text-gray-700">Kafka broker会定期执行日志清理任务，这一过程由后台线程管理。</p>
                    </div>
                    
                    <div class="timeline-item">
                        <h3 class="font-bold text-lg text-gray-800 mb-2">查找过期数据</h3>
                        <p class="text-gray-700">根据配置的保留时间或大小，Kafka会扫描分区中的日志，查找需要被清理的消息。</p>
                    </div>
                    
                    <div class="timeline-item">
                        <h3 class